// =====================
// =  DOM 元素获取
// =====================

// 文件选择输入框
const fileInput = document.getElementById('file-input');
// 用于显示 PDF 内容的容器（canvas 所在的 div）
const container = document.getElementById('pdf-container');
// PDF 滚动容器（用于记录滚动位置）
const scrollContainer = document.getElementById('pdf-scroll-container');
// 显示当前缩放比例的元素（如：100%）
const zoomIndicator = document.getElementById('zoom-indicator');

// =====================
// =  状态与变量定义
// =====================

// 交互与渲染控制
let dragRafId = null;        // 用于存储注释拖拽时的 requestAnimationFrame ID，优化性能
let isEditing = false;       // 标记当前是否正在编辑注释内容（防止重复编辑）

// 滚动位置记录
let lastScrollTop = 0;       // 保存 PDF 容器的垂直滚动位置（用于缩放后恢复视图）
let lastScrollLeft = 0;      // 保存 PDF 容器的水平滚动位置（用于缩放后恢复视图）

// 数据持久化与延迟保存
let saveTimeout = null;      // 用于延迟保存注释内容的定时器 ID（防抖）

// PDF 页面与状态
let currentPage = null;      // 当前加载的 PDF 页面对象（来自 pdf.js）
let viewportScale = 1.0;     // 当前 PDF 的缩放比例（1.0 表示 100%）

// 文件标识与缓存
let currentFileKey = null;   // 当前文件的唯一标识符（文件名+大小），用于本地存储注释
let originalPdfBytes = null; // 存储原始 PDF 文件的字节数组，用于导出带注释的 PDF

// 注释管理
let annotationElements = []; // 存储所有注释元素的数组，用于更新和保存注释位置
let selectedAnnotation = null; // 当前选中的注释元素，用于删除或编辑

// =====================
// =  事件监听器
// =====================

/**
 * 监听滚动事件，记录当前滚动位置
 * 用于在缩放或重新渲染时恢复滚动位置
 */
scrollContainer.addEventListener('scroll', () => {
    lastScrollLeft = scrollContainer.scrollLeft;
    lastScrollTop = scrollContainer.scrollTop;
});

/**
 * 文件选择事件监听器
 * 当用户选择一个 PDF 文件后，读取并加载第一页内容
 */
fileInput.addEventListener('change', function (e) {
    const file = e.target.files[0];
    if (!file) return;

    // 构造当前文件的唯一标识 key，用于本地存储注释
    currentFileKey = `${file.name}-${file.size}`;

    const reader = new FileReader();

    // 文件读取完成后
    reader.onload = function () {
        const typedArray = new Uint8Array(reader.result);

        // 使用 pdf.js 加载 PDF 文件
        pdfjsLib.getDocument({ data: typedArray }).promise.then(pdf => {
            // 加载第一页
            pdf.getPage(1).then(page => {
                currentPage = page;
                renderPDF();          // 渲染当前页面
                loadAnnotations();    // 加载本地存储的注释
            });
        }).catch(err => {
            console.error('加载 PDF 出错:', err);
            alert('加载 PDF 出错，请检查文件格式是否正确');
        });
    };

    reader.readAsArrayBuffer(file);
});

// =====================
// =  工具函数
// =====================

/**
 * 更新缩放比例显示
 * 在缩放按钮点击或重置缩放后更新界面上的百分比显示
 */
function updateZoomDisplay() {
    const percent = Math.round(viewportScale * 100);
    zoomIndicator.textContent = `${percent}%`;
}

/**
 * 渲染当前 PDF 页面到 canvas 上
 * 根据当前缩放比例重新绘制页面，并更新注释位置
 */
function renderPDF() {
    if (!currentPage) return;

    // 获取当前页面的视口信息（基于缩放比例）
    const viewport = currentPage.getViewport({ scale: viewportScale });
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    const outputScale = window.devicePixelRatio || 1;

    // 设置 canvas 分辨率，确保高 DPI 屏幕下清晰
    canvas.width = Math.floor(viewport.width * outputScale);
    canvas.height = Math.floor(viewport.height * outputScale);
    canvas.style.width = `${viewport.width}px`;
    canvas.style.height = `${viewport.height}px`;
    context.scale(outputScale, outputScale);

    // 替换旧的 canvas 或添加新 canvas
    const oldCanvas = container.querySelector('canvas');
    if (oldCanvas) {
        container.replaceChild(canvas, oldCanvas);
    } else {
        container.appendChild(canvas);
    }

    // 开始渲染 PDF 页面
    currentPage.render({
        canvasContext: context,
        viewport: viewport
    });

    // 设置容器大小与当前页面一致
    container.style.width = canvas.style.width;
    container.style.height = canvas.style.height;

    // 恢复之前的滚动位置
    setTimeout(() => {
        scrollContainer.scrollLeft = lastScrollLeft;
        scrollContainer.scrollTop = lastScrollTop;
    }, 0);

    // 更新所有注释元素的显示位置
    annotationElements.forEach(el => {
        const pdfX = parseFloat(el.dataset.pdfX);
        const pdfY = parseFloat(el.dataset.pdfY);
        const displayX = pdfX * viewportScale;
        const displayY = pdfY * viewportScale;

        el.style.left = `${displayX}px`;
        el.style.top = `${displayY}px`;
        el.style.transform = `translate(-50%, -50%)`;
        el.style.setProperty('--scale', viewportScale);
        el.setAttribute('data-x', displayX);
        el.setAttribute('data-y', displayY);
    });
}

// =====================
// =  缩放控制函数
// =====================

/**
 * 放大 PDF 页面
 * 每次点击放大 0.2 倍，最大放大到 3 倍
 */
function zoomIn() {
    lastScrollLeft = scrollContainer.scrollLeft;
    lastScrollTop = scrollContainer.scrollTop;
    viewportScale = Math.min(3, viewportScale + 0.2);
    renderPDF();
    updateZoomDisplay();
}

/**
 * 缩小 PDF 页面
 * 每次点击缩小 0.2 倍，最小缩小到 0.5 倍
 */
function zoomOut() {
    lastScrollLeft = scrollContainer.scrollLeft;
    lastScrollTop = scrollContainer.scrollTop;
    viewportScale = Math.max(0.5, viewportScale - 0.2);
    renderPDF();
    updateZoomDisplay();
}

/**
 * 重置缩放比例为 1.0（100%）
 */
function resetZoom() {
    viewportScale = 1.0;
    renderPDF();
    updateZoomDisplay();
}

// =====================
// =  注释功能函数
// =====================

/**
 * 添加一个新的注释元素
 * @param {number} pdfX - 注释在 PDF 页面上的 X 坐标（逻辑坐标，非像素）
 * @param {number} pdfY - 注释在 PDF 页面上的 Y 坐标（逻辑坐标，非像素）
 * @param {string} text - 注释文本内容
 */
function addAnnotation(pdfX = 100, pdfY = 100, text = '双击编辑') {
    const id = Math.random().toString(36).substr(2, 9);

    const displayX = pdfX * viewportScale;
    const displayY = pdfY * viewportScale;

    const textEl = document.createElement('div');
    textEl.className = 'annotation';
    textEl.style.left = `${displayX}px`;
    textEl.style.top = `${displayY}px`;
    textEl.style.transform = 'translate(-50%, -50%)';
    textEl.style.setProperty('--scale', viewportScale);
    textEl.innerText = text;
    textEl.dataset.id = id;
    textEl.dataset.pdfX = Math.round(pdfX * 100) / 100;
    textEl.dataset.pdfY = Math.round(pdfY * 100) / 100;
    textEl.setAttribute('data-x', displayX);
    textEl.setAttribute('data-y', displayY);

    annotationElements.push(textEl);

    // 双击注释进入编辑模式
    textEl.addEventListener('dblclick', function () {
        const existingInput = container.querySelector('.annotation-input');
        if (existingInput) return;

        const input = document.createElement('textarea');
        input.className = 'annotation-input';
        input.value = textEl.innerText;

        input.style.left = textEl.style.left;
        input.style.top = textEl.style.top;
        input.style.width = textEl.offsetWidth + 'px';
        input.style.height = textEl.offsetHeight + 'px';

        container.appendChild(input);
        input.focus();

        function saveText() {
            if (input.value.trim()) {
                textEl.innerText = input.value;
                saveAnnotations();
            }
            input.remove();
        }

        input.addEventListener('blur', saveText);
        input.addEventListener('keydown', function (e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                saveText();
            }
        });
    });

    // 拖拽注释功能
    interact(textEl).draggable({
        onmove: function (event) {
            const target = event.target;

            const currentLeft = parseFloat(target.style.left) || 0;
            const currentTop = parseFloat(target.style.top) || 0;

            const dx = currentLeft + event.dx;
            const dy = currentTop + event.dy;

            target.style.left = dx + 'px';
            target.style.top = dy + 'px';
            target.style.transform = 'translate(-50%, -50%)';

            if (dragRafId) {
                cancelAnimationFrame(dragRafId);
            }

            dragRafId = requestAnimationFrame(() => {
                const pdfX = dx / viewportScale;
                const pdfY = dy / viewportScale;

                target.dataset.pdfX = Math.round(pdfX * 100) / 100;
                target.dataset.pdfY = Math.round(pdfY * 100) / 100;

                dragRafId = null;
            });

            if (saveTimeout) {
                clearTimeout(saveTimeout);
            }

            saveTimeout = setTimeout(() => {
                saveAnnotations();
                saveTimeout = null;
            }, 300);
        },
        onend: function () {
            if (dragRafId) {
                cancelAnimationFrame(dragRafId);
                dragRafId = null;
            }

            if (saveTimeout) {
                clearTimeout(saveTimeout);
                saveTimeout = null;
            }

            saveAnnotations();
        }
    });

    container.appendChild(textEl);

    saveAnnotations();
}

/**
 * 保存当前所有注释数据到 localStorage
 * 以当前文件 key 为键存储，确保注释不会混淆
 */
function saveAnnotations() {
    if (!currentFileKey) return;

    const annotations = [];
    annotationElements.forEach(el => {
        const id = el.dataset.id;
        const x = parseFloat(el.dataset.pdfX);
        const y = parseFloat(el.dataset.pdfY);
        annotations.push({
            id,
            text: el.innerText,
            x,
            y
        });
    });

    localStorage.setItem(`annotations-${currentFileKey}`, JSON.stringify(annotations));
}

/**
 * 从 localStorage 中加载注释数据并重新创建注释元素
 */
function loadAnnotations() {
    if (!currentFileKey) return;

    const saved = JSON.parse(localStorage.getItem(`annotations-${currentFileKey}`) || '[]');
    if (saved.length === 0) {
        annotationElements.forEach(el => el.remove());
        annotationElements = [];
        return;
    }

    annotationElements.forEach(el => el.remove());
    annotationElements = [];

    saved.forEach(data => {
        addAnnotation(data.x, data.y, data.text);
    });
}

// =====================
// =  注释选择与删除
// =====================

/**
 * 点击页面时判断是否点击了注释
 * 如果点击了，标记为选中状态
 */
container.addEventListener('click', (e) => {
    annotationElements.forEach(el => {
        el.classList.remove('selected');
    });

    if (e.target.classList.contains('annotation')) {
        selectedAnnotation = e.target;
        selectedAnnotation.classList.add('selected');
    } else {
        selectedAnnotation = null;
    }
});

/**
 * 键盘事件监听：删除选中的注释
 */
document.addEventListener('keydown', function (e) {
    if (e.key === 'Delete' || e.key === 'Backspace') {
        if (document.activeElement && document.activeElement.classList.contains('annotation-input')) {
            return;
        }

        if (selectedAnnotation) {
            selectedAnnotation.remove();
            annotationElements = annotationElements.filter(el => el !== selectedAnnotation);
            selectedAnnotation = null;
            saveAnnotations();
        }
    }
});

// =====================
// =  PDF 导出功能
// =====================

/**
 * 保存原始 PDF 的字节数据（用于导出时嵌入）
 */
async function saveOriginalPdfBytes() {
    const file = fileInput.files[0];
    if (!file) return;

    const reader = new FileReader();
    return new Promise((resolve, reject) => {
        reader.onload = function () {
            originalPdfBytes = new Uint8Array(reader.result);
            resolve();
        };
        reader.onerror = () => reject(reader.error);
        reader.readAsArrayBuffer(file);
    });
}

/**
 * 导出带注释的 PDF
 * 使用 html2canvas 截图 PDF 容器，并使用 PDFLib 生成 PDF 文件
 */
async function exportToPDF() {
    const container = document.getElementById('pdf-container');
    if (!container) {
        alert('未找到 #pdf-container');
        return;
    }

    const annotations = container.querySelectorAll('.annotation');
    const originalStyles = [];

    // 临时隐藏注释样式用于截图
    annotations.forEach(el => {
        originalStyles.push({
            el,
            border: el.style.border,
            background: el.style.background,
            padding: el.style.padding,
            boxShadow: el.style.boxShadow,
            pointerEvents: el.style.pointerEvents,
            classList: [...el.classList]
        });

        el.style.border = 'none';
        el.style.background = 'transparent';
        el.style.padding = el.style.padding;
        el.style.boxShadow = 'none';
        el.style.pointerEvents = 'none';
        el.classList.remove('selected');
    });

    try {
        console.log('开始截图...');
        const canvas = await html2canvas(container, {
            scale: 2,
            backgroundColor: null,
            useCORS: true,
            logging: false,
            imageTimeout: 15000,
        });
        console.log('截图完成 ✅');

        const pdfDoc = await PDFLib.PDFDocument.create();
        const pageWidth = canvas.width;
        const pageHeight = canvas.height;
        const page = pdfDoc.addPage([pageWidth, pageHeight]);

        const pngImage = await pdfDoc.embedPng(canvas.toDataURL('image/png'));
        page.drawImage(pngImage, {
            x: 0,
            y: 0,
            width: pageWidth,
            height: pageHeight,
        });

        const pdfBytes = await pdfDoc.save();
        const blob = new Blob([pdfBytes], { type: 'application/pdf' });

        const file = fileInput.files[0];
        let originalName = '未命名文件';

        if (file) {
            originalName = file.name.replace(/\.[^/.]+$/, "");
        }

        const timestamp = new Date().toISOString().replace(/[^0-9]/g, '').slice(0, 14);
        const downloadName = `${originalName}_${timestamp}.pdf`;

        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = downloadName;
        link.click();

        console.log(`PDF 导出成功：${downloadName} ✅`);
    } catch (err) {
        console.error('导出失败 ❌', err);
        alert('导出失败，请查看控制台日志');
    } finally {
        // 恢复注释样式
        annotations.forEach((el, index) => {
            const original = originalStyles[index];

            el.style.border = original.border;
            el.style.background = original.background;
            el.style.padding = original.padding;
            el.style.boxShadow = original.boxShadow;
            el.style.pointerEvents = original.pointerEvents;

            el.classList.remove(...el.classList);
            el.classList.add(...original.classList);
        });
    }
}